﻿package com.zouloux.physics 
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	/**
	 * ...
	 * @author ZoulouX
	 */
	public class PhysicsConstraint extends APhysicsObject implements IPhysicsObject
	{
		// Les distances
		protected var _minDistance				:Number 			= 0;
		protected var _maxDistance				:Number 			= 0;
		
		// Les points
		protected var _pointA					:APhysicsObject;
		protected var _pointB					:APhysicsObject;
		
		// Les getters
		public function get minDistance():Number { return _minDistance; }
		public function get maxDistance():Number { return _maxDistance; }
		public function get pointA():APhysicsObject { return _pointA; }
		public function get pointB():APhysicsObject { return _pointB; }
		public function get distance():Number { return _maxDistance; }
		
		// Les setters
		public function set minDistance(value:Number):void 
		{
			_minDistance = value;
		}
		public function set maxDistance(value:Number):void 
		{
			_maxDistance = value;
		}
		public function set pointA(value:APhysicsObject):void 
		{
			_pointA = value;
		}
		public function set pointB(value:APhysicsObject):void 
		{
			_pointB = value;
		}
		public function set distance(value:Number):void 
		{
			_minDistance = value;
			_maxDistance = value;
		}
		
		// Le constructeur
		public function PhysicsConstraint (pPointA:APhysicsObject, pPointB:APhysicsObject, pMinDistance:Number = 0, pMaxDistance:Number = 0)
		{
			// Construire le parent
			super();
			
			// Enregistrer les valeurs
			_minDistance = pMinDistance;
			_maxDistance = pMaxDistance;
			_pointA = pPointA;
			_pointB = pPointB;
			
			graphics.beginFill(0, 1);
			graphics.drawRect( - _maxDistance / 2, -2, _maxDistance, 3);
		}
		
		// Actualiser
		override public function update ():void
		{
			// Vérifier la présence des points
			if (_pointA != null && _pointB != null)
			{
				// Calculer les distances en x et en y
				var distanceX:Number = (_pointA.x - _pointB.x);
				var distanceY:Number = (_pointA.y - _pointB.y);
				
				// Calculer la distance entre le point A et le point B
				var distance:Number = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
				
				// Calculer l'angle entre A et B
				var angle:Number = Math.atan2(distanceX, distanceY);
				
				// Calculer les corrections
				var correctionMin:Number = distance - _minDistance;
				var correctionMax:Number = distance - _maxDistance;
				
				// Les corrections en X et en Y
				var xCorrection:Number = 0;
				var yCorrection:Number = 0;
				
				// Appliquer les corrections
				if (distance < _minDistance)
				{
					// La correction minimum en x et en y
					xCorrection = Math.sin(angle) * correctionMin;
					yCorrection = Math.cos(angle) * correctionMin;
				}
				if (distance > _maxDistance)
				{
					// La correction minimum en x et en y
					xCorrection = Math.sin(angle) * correctionMax;
					yCorrection = Math.cos(angle) * correctionMax;
				}
				
				// Appliquer les corrections sur A
				_pointA.x -= xCorrection / 2;
				_pointA.y -= yCorrection / 2;
				
				// Appliquer les corrections sur B
				_pointB.x += xCorrection / 2;
				_pointB.y += yCorrection / 2;
				
				// Transferrer les forces
				/*
				_pointA.velocityX -= -Math.sin(angle) * speed / 2;
				_pointA.velocityY -= -Math.cos(angle) * speed / 2;
				_pointB.velocityX -= Math.sin(angle) * speed / 2
				_pointB.velocityY -= Math.cos(angle) * speed / 2
				*/
				
				// Appliquer la rotation et la position
				rotation = -angle / Math.PI * 180 - 90;
				x = _pointB.x + distanceX / 2;
				y = _pointB.y + distanceY / 2;
			}
		}
	}
}